from flask import Blueprint, request, jsonify
import os
import json
import sys
import traceback
from typing import List
from utils import getResponse, CLIENT_DIR

# 将搜索目录改为目录
sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), os.pardir,os.pardir))
from src.scripts.util.ClientUtil import ClientUtil
from app.utils import shared_executor

# 创建蓝图
orchestrate_bp = Blueprint('orchestrate', __name__)


@orchestrate_bp.route("/web2/orchestrate", methods=["POST"])
def orchestrate():
    """
    编排服务
    """
    orchestrattion_file: dict = json.loads(request.form.get("orchestration_file", ""))
    client_name: str = orchestrattion_file.get("name", "").strip()
    client_id: str = orchestrattion_file.get("id", "").strip()
    if client_id == "" or client_name == "":
        return getResponse(400, "client_id or client_name is empty")
    
    node_list: List[dict] = list()
    for node in orchestrattion_file.get("nodes", []):
        res: dict = dict()
        res["type"] = node.get("type", "").strip()
        res["id"] = node.get("id", "").strip()
        res["name"] = node.get("file", "").split("/")[-1].split(".")[0].strip()
        res["method"] = node.get("method", "").strip()
        res["module"] = node.get("module", "").strip()
        res["topic"] = node.get("topic", "").strip()
        res["struct_name"] = node.get("struct_name", "").strip()
        res["struct"] = node.get("struct", "").strip()
        res["dataBind"] = node.get("dataBind", dict())
        
        if (
            res["type"] == "SERVICE"
            and res["method"] == ""
            and res["dataBind"] == dict()
        ):
            return getResponse(400, f"title {res.get('title', '')} : method or dataBind is empty")
        node_list.append(res)
    
    orchestrattion_info: dict = dict()
    orchestrattion_info["name"] = client_name
    orchestrattion_info["id"] = client_id
    orchestrattion_info["nodes"] = node_list
    orchestrattion_info["connections"] = orchestrattion_file.get("connections", [])
    
    if orchestrattion_info["connections"] == []:
        return getResponse(400, "connections is empty")
    if len(orchestrattion_info["nodes"]) == 0:
        return getResponse(400, "nodes is empty")

    print(json.dumps(orchestrattion_info, indent=4, ensure_ascii=False))

    # 使用共享线程池异步执行
    shared_executor.submit(async_process_client, orchestrattion_info, False)

    return getResponse(200, "orchestrate success")

@orchestrate_bp.route("/dds", methods=["POST"])
def orchestrate_dds():
    """
    编排服务
    """
    # 接收数据
    try:
        orchestrattion_json:dict = request.get_json()
    except:
        return getResponse(400, "json format error")
    if type(orchestrattion_json) != dict:
        return getResponse(400, "json format error")
    
    # 处理数据
    process_dict:dict = dict()
    process_dict["name"] = orchestrattion_json.get("name", "")
    process_dict["id"] = orchestrattion_json.get("id", "")
    # 处理节点
    process_dict["nodes"] = list()
    for node in orchestrattion_json.get("nodes", []):
        new_node:dict = dict()
        new_node["type"] = node.get("type","")
        new_node["id"] = node.get("id","")
        new_node["name"] = node.get("name","")
        new_node["method"] = node.get("method",dict()).get("name","")
        new_node["dataBind"] = dict()
        new_node["dataBind"]["input"] = ""
        new_node["dataBind"]["output"] = ""
        process_dict["nodes"].append(new_node)
    # 处理连接
    process_dict["connections"] = list()
    for conn in orchestrattion_json.get("connections", []):
        new_conn:dict = dict()
        new_conn["source"] = conn.get("source", "")
        new_conn["target"] = conn.get("target", "")
        new_conn["condition"] = conn.get("condition", "")
        new_conn["ddsCondition"] = conn.get("ddsCondition", "")
        process_dict["connections"].append(new_conn)

    # 保存处理后文件到新的client文件夹
    with open(f"example_{process_dict.get('name', '')}_processed.json", 'w') as file:
        file.write(json.dumps(process_dict,indent=4,ensure_ascii=False))
    # 生成客户端代码
    # 使用共享线程池异步执行
    shared_executor.submit(async_process_client, process_dict, True)

    return getResponse(200, "orchestrate success")



def async_process_client(orchestration_info: dict, is_dds: bool = False):
    """
    异步处理客户端生成
    :param orchestration_info: 编排信息字典
    :param is_dds_only: 是否只处理DDS客户端
    """
    try:
        if not is_dds:
            # 处理同步客户端
            ClientUtil.accomplishAllSyncClient(orchestration_info)
        else:
            # 处理DDS客户端
            ClientUtil.accomplishAllDDSClient(orchestration_info)
    except Exception as e:
        # 获取完整的异常栈信息
        stack_trace = traceback.format_exc()
        # 实际应用中应该添加日志记录，这里先打印出来展示完整异常栈
        print(f"异步处理客户端失败: {str(e)}\n完整异常栈信息如下：\n{stack_trace}")